#include "../Card.h"
#include "../Logic.h"
#include "../Table.h"
#include "../Deck.h"
#include <assert.h>
#include <vector>
#include<iostream>

#define VERBOSE 0

using namespace std;

int main(){

Card card1(hearts, _4, 0);
Card card2(spades, jack, 1);
Card card3(diamonds, _2, 2);
Card card4(diamonds, ace, 3);
Card card5(spades, _10, 4);
Card card6(clubs, joker, 5);
Card card7(clubs, _4, 6);


Deck* deck = new Deck();

deck->add(&card1);
deck->add(&card2);
deck->add(&card3);
deck->add(&card4);
deck->add(&card5);
deck->add(&card6);

Player* player1 = new Player();

deck->add(player1->getArmy());

Table* table = new Table(4);

table->spoilsPile = *deck;

Logic* logic = new Logic(); 

logic->setTable(table);


/*Test removeSpoils()*/
logic->removeSpoils();

assert(table->spoilsPile.size() == 0);

#if VERBOSE
  cout<<"Test successful!"<<endl;
#endif

/*Test getMovingPlayers()*/

table->warTime = 0;

table->soloMover = player1;

vector<Player*> result = logic->getMovingPlayers();

assert(result.at(0) == player1 && result.size() == 1);

#if VERBOSE
  cout<<"Test successful!"<<endl;
#endif

table->warTime = 1;

result.clear();

table->players.at(1).setWarFlag(true);
table->players.at(3).setWarFlag(true);


result = logic->getMovingPlayers();

assert(result.at(0) == &table->players.at(1) && result.at(1) == &table->players.at(3));

#if VERBOSE
  cout<<"Test successful!"<<endl;
#endif


/*Test setActive()*/

table->players.at(0).getHand()->add(deck);

Card* p0Card = table->players.at(0).getHand()->draw();

logic->setActive(p0Card, &table->players.at(0));

assert(table->activeCards.size() == 1 && table->activeCards.at(0) == p0Card);

#if VERBOSE
  cout<<"Test successful!"<<endl;
#endif

table->players.at(1).getHand()->add(deck);

table->players.at(1).getHand()->draw();
table->players.at(0).getHand()->draw();

Card* p1Card = table->players.at(1).getHand()->draw();

logic->setActive(p1Card, &table->players.at(1));

p0Card = table->players.at(0).getHand()->draw();

logic->setActive(p0Card, &table->players.at(0));

assert(table->activeCards.size() == 2 && table->activeCards.at(1) == p1Card && table->activeCards.at(0) == p0Card);

assert(table->pillagePile.size() == 1);

#if VERBOSE
  cout<<"Test successful!"<<endl;
#endif

/*Tests taxPlayer()*/

table->players.at(0).getArmy()->draw(27);

table->players.at(0).getArmy()->add(deck);

table->spoilsPile.draw(2);

logic->taxPlayer(&table->players.at(0), 2);
 
assert(table->players.at(0).getArmy()->size() == 4 && table->players.at(0).getArmy()->draw() == &card3);
 
assert(table->spoilsPile.size() == 2);

#if VERBOSE
  cout<<"Test successful!"<<endl;
#endif

table->players.at(1).setOwner(&table->players.at(0));

table->spoilsPile.draw(2);

logic->taxPlayer(&table->players.at(0), 2);

assert(table->players.at(0).getArmy()->size() == 1 && table->players.at(0).getArmy()->draw() == &card6); 

assert(table->spoilsPile.size() == 2);

table->players.at(1).setOwner(NULL);

#if VERBOSE
  cout<<"Test successful!"<<endl;
#endif


/*Test processSoloMove()*/

table->soloMover = &table->players.at(1);

table->players.at(2).getArmy()->draw(40);
table->players.at(2).getHand()->draw(10);

logic->processSoloMove();

assert(table->soloMover == &table->players.at(3));

logic->processSoloMove();

assert(table->soloMover == &table->players.at(0));

#if VERBOSE
  cout<<"Test successful!"<<endl;
#endif


/*Test giveBattleReward() (non-war case)*/

table->warTime = false;
table->players.at(0).getArmy()->draw(40);
table->players.at(1).getArmy()->draw(40);

table->pillagePile.draw(40);
table->activeCards.draw(40);
table->spoilsPile.draw(40);

table->players.at(0).setOwner(&table->players.at(1));

table->players.at(0).getArmy()->add(deck);
table->players.at(1).getArmy()->add(deck);

table->pillagePile.add(deck);
table->activeCards.add(deck);


logic->giveBattleReward(&table->players.at(1));


assert(table->players.at(1).getArmy()->size() == 18);

table->pillagePile.add(deck);
table->activeCards.add(deck);
logic->giveBattleReward(&table->players.at(0));
assert(table->players.at(1).getArmy()->size() == 30);

#if VERBOSE
  cout<<"Test successful!"<<endl;
#endif


/*Test doBattle()*/

table->activeCards.draw(40);
table->activeCards.add(&card1);
table->activeCards.add(&card2);

table->warTime = false;
assert(logic->doBattle() == false);

table->activeCards.add(&card3);
table->activeCards.add(&card4);

//cout<<table->activeCards.size()<<endl;

card1.setOwner(&table->players.at(0));
card2.setOwner(&table->players.at(1));
card3.setOwner(&table->players.at(2));
card4.setOwner(&table->players.at(3));

table->warTime = false;
logic->doBattle();


assert(table->soloMover == &table->players.at(1));

table->activeCards.draw(40);
table->activeCards.add(&card1);
table->activeCards.add(&card2);
table->activeCards.add(&card3);
table->activeCards.add(&card7);

card1.setOwner(&table->players.at(0));
card2.setOwner(&table->players.at(1));
card3.setOwner(&table->players.at(2));
card7.setOwner(&table->players.at(3));

table->warTime = false;

logic->doBattle();

assert(table->warTime == true);
assert(table->players.at(0).getWarFlag() == true && table->players.at(3).getWarFlag() == true);

#if VERBOSE
  cout<<"Test successful!"<<endl;
#endif



/*Test updateActiveCard()*/

table->warTime = false;

table->players.at(0).setWarFlag(false);
table->players.at(0).setMoveCard(NULL);

table->players.at(1).setWarFlag(false);
table->players.at(1).setMoveCard(NULL);

table->activeCards.draw(40);

logic->updateActiveCard();

assert(table->activeCards.size() == 0);

#if VERBOSE
cout<<"Test successful!"<<endl;
#endif

table->players.at(0).getHand()->draw(6);

table->players.at(0).getHand()->add(&card1);
table->players.at(0).getHand()->add(&card2);
table->players.at(0).getHand()->add(&card4);


table->players.at(0).setMoveCard(&card1);

card1.setOwner(&table->players.at(0));

table->players.at(0).getArmy()->draw(40);

table->players.at(0).getArmy()->add(&card3);

table->soloMover = &table->players.at(0);

logic->updateActiveCard();

assert(table->players.at(0).getMoveCard() == NULL);
assert(table->players.at(0).getWarFlag() == false);

assert(table->players.at(0).getHand()->size() == 3);

assert(table->players.at(0).getHand()->at(2) == &card3);

#if VERBOSE
cout<< "Test successful!" << endl;
#endif

/*Test reviveVassals()*/

table->players.at(0).getHand()->draw(40);
table->players.at(1).getHand()->draw(40);
table->players.at(2).getHand()->draw(40);
table->players.at(3).getHand()->draw(40);

table->players.at(0).getArmy()->draw(40);
table->players.at(1).getArmy()->draw(40);
table->players.at(2).getArmy()->draw(40);
table->players.at(3).getArmy()->draw(40);

table->players.at(1).getArmy()->add(deck);
table->players.at(2).getArmy()->add(deck);
table->players.at(3).getArmy()->add(deck);

table->players.at(1).getHand()->add(&card2);
table->players.at(2).getHand()->add(&card3);
table->players.at(3).getHand()->add(&card4);

table->players.at(0).setOwner(NULL);
table->players.at(1).setOwner(NULL);
table->players.at(2).setOwner(&table->players.at(0));
table->players.at(3).setOwner(NULL);

table->players.at(0).addVassal(&table->players.at(2));

table->soloMover = &table->players.at(0);

logic->reviveVassals();

assert(table->players.at(0).getIsVassal() == true);
assert(table->players.at(2).getIsVassal() == false);
assert(table->players.at(1).getIsVassal() == false);
assert(table->players.at(3).getIsVassal() == false);

assert(table->players.at(0).getOwner() == &table->players.at(1));
/* EVIL HERE, NEED TO PUSH. */
//assert(table->players.at(0).getHand()->size() == 1);
assert(table->players.at(1).getArmy()->size() == 5);

#if VERBOSE
cout<<"Test successful!"<<endl;
#endif


cout << "Logic has passed test set B." << endl;

return 0;

}





